const defaultOpt = {
  width: 100,
  height: 100,
  bgStyle: {
    top: 0,
    left: 0,
    'z-index': 9999,
    'background-repeat': 'repeat'
  },
  text: `新视窗vue`,
  fontSize: '14px',
  fontStyle: '黑体',
  textAlign: 'center',
  color: 'rgba(100,100,100,0.2)',
  degree: -20,
  repeat: true
}

/**
 * @description:
 * @param {object} obj
 * @return {*}
 */
function objToDomString(obj) {
  if (Object.prototype.toString.call(obj) !== '[object Object]') return ''
  return Object.entries(obj).reduce((pre, [key, value]) => {
    pre = `${pre}${key}: ${value};`
    return pre
  }, '')
}

/**
 * @param {Object} ctx canvas上下文
 * @param {String} text 需要输入的文本
 * @param {Number} x X轴起始位置
 * @param {Number} y Y轴起始位置
 * @param {Number} maxWidth 单行最大宽度
 * @param {Number} lineHeight 行高
 */
function drawRowsText(ctx, text, x, y, maxWidth, lineHeight) {
  let arrText
  if (Array.isArray(text)) {
    arrText = text
  } else {
    arrText = text.split(',')
  }
  let line = ''
  for (let n = 0; n < arrText.length; n++) {
    const testLine = line + arrText[n]
    const metrics = ctx.measureText(testLine)
    const testWidth = metrics.width
    if (testWidth > maxWidth && n > 0) {
      ctx.fillText(line, x, y)
      line = arrText[n]
      y += lineHeight
    } else {
      line = testLine
    }
  }
  ctx.fillText(line, x, y)
}

class waterMark {
  constructor(opt = {}) {
    this.CONTAINERID = `water-canvas-${Date.now()}`
    this.styleStr = ''
    this.drawCanvas = this.drawCanvas.bind(this)
    this.parentObserver = this.parentObserver.bind(this)
    this.repaint = this.repaint.bind(this)
    this.isOberserve = false // 监听变动
    this.init(opt)
    this.drawCanvas()
    this.parentObserver()
  }

  init(opt) {
    this.option = Object.assign(defaultOpt, opt)
  }

  drawCanvas() {
    this.isOberserve = true
    const divContainer = document.createElement('div')
    divContainer.id = this.CONTAINERID
    const { option } = this
    // 绘制文字
    const canvas = document.createElement('canvas')
    const context = canvas.getContext('2d')
    if (context) {
      canvas.width = option.width
      canvas.height = option.height
      context.font = `${option.fontSize} ${option.fontStyle}`
      context.textAlign = option.textAlign
      context.fillStyle = option.color
      context.translate(canvas.width / 2, canvas.height / 2)
      context.rotate((option.degree * Math.PI) / 180)
      context.fillText(option.text, 0, 0)
    }

    const backgroundUrl = canvas.toDataURL('image/png')
    // 插入水印图片
    const hasCustomId = option.id
    let el
    if (hasCustomId) el = document.getElementById(hasCustomId)

    const insetStyleObj = {
      position: `${hasCustomId ? 'absolute' : 'fixed'}`,
      width: `${hasCustomId ? el.offsetWidth + 'px' : '100%'}`,
      height: `${hasCustomId ? el.offsetHeight + 'px' : '100%'}`,
      'background-image': `url(${backgroundUrl})`
    }
    const finallyBgStyle = Object.assign(insetStyleObj, option.bgStyle, {
      'pointer-events': 'none'
    })
    this.styleStr = objToDomString(finallyBgStyle) ?? ''
    divContainer.setAttribute('style', this.styleStr)

    if (el) {
      // 按照当前元素进行定位
      el.setAttribute('style', 'position: relative')
      el.appendChild(divContainer)
    } else {
      document.body.appendChild(divContainer)
    }

    // this.wmObserver(divContainer)
    this.isOberserve = false
  }

  wmObserver(divContainer) {
    const wmConf = { attributes: true, childList: true, characterData: true }
    const wmObserver = new MutationObserver((mo) => {
      if (!this.isOberserve) {
        const _obj = mo[0].target
        _obj.setAttribute('style', this.styleStr)
        _obj.setAttribute('id', this.CONTAINERID)
        wmObserver.takeRecords()
      }
    })
    wmObserver.observe(divContainer, wmConf)
  }

  parentObserver() {
    const bodyObserver = new MutationObserver((mo) => {
      if (!this.isOberserve) {
        const __wm = document.querySelector(`#${this.CONTAINERID}`)

        if (__wm && __wm.getAttribute('style') !== this.styleStr) {
          __wm.setAttribute('style', this.styleStr)
        }
        // 重绘水印
        setTimeout(() => {
          bodyObserver.disconnect()
          this.repaint()
        })
      }
    })
    const el = document.querySelector(`#${this.CONTAINERID}`)
    const parent = el?.parentNode
    if (el && parent) {
      bodyObserver.observe(parent, {
        attributes: true,
        childList: true
      })
    }
  }

  repaint(opt = {}) {
    this.remove()
    this.init(opt)
    this.drawCanvas()
    this.parentObserver()
  }

  remove() {
    this.isOberserve = true
    const _wm = document.querySelector(`#${this.CONTAINERID}`)
    const _wmParent = _wm?.parentNode
    _wm && _wmParent.removeChild(_wm)
  }
}

/**
 * 参数 {Object} opt
 * @param {String} text    水印文本，默认'新视窗'
 * @param {String} font    水印字体，默认'30px 黑体'
 * @param {Int} canvasWidth    单个水印容器宽度，默认500
 * @param {Int} canvasHeight    单个水印容器高度，默认200
 * @param {String} textAlign    水印文本对齐方式，默认'center'
 * @param {String} textStyle    水印文本样式，默认'rgba(100,100,100,0.15)'
 * @param {Int} degree    水印文本旋转角度，默认 -20
 * @param return
 **/
function domWatermark(opt = {}) {
  return new waterMark(opt)
}
